---
title: Upgrade to Solito 4
id: v4
sidebar_label: Upgrade to v4
image: https://solito.dev/img/4.png
---

Solito 4 is an exciting step for the React Native + Next.js Stack. **You can now use React Native with the Next.js App Router.**

This version has no breaking changes and is backwards compatible with the `pages` folder. It introduces a number of new hooks and imports to let you build with the Next.js App Directory.

In typical Solito fashion, any new functionality will mirror the Next.js import paths and APIs as closely as possible.

## Upgrade Guide

1. `yarn add solito` from `packages/app`
2. `yarn add next` from `apps/next`

## New Features

### `solito/navigation`

Following the Next.js approach, there is now a new import, `solito/navigation`, for the App Router hooks. When building a page in the `app` directory, you will use this instead of other imports you may be used to for hooks, such as `solito/router`.

[See the docs for all hooks.](https://solito.dev/app-directory/hooks)

The following hooks are added:

- `useRouter`: Similar to the `useRouter` hook from `solito/router`, adapted for the App Router by following the `next/navigation` conventions. It has the same behavior on iOS and Android.
- `useParams`: Read dynamic segment parameters (`/users/[userId]`) as `{ userId: string }`.
- `useSearchParams`: Read URL search parameters using the `URLSearchParams` class.
- `usePathname`: The much-requested hook to read the current path. On native, this is only safe if you're using Expo Router. This hook may change in the future, depending on its stability on native.
- `useUpdateSearchParams`: A convenience hook to update search parameters as an object. Calls `setParams` on native, and `router.push` or `router.replace` on Web (configurable).
- `useLink` The same hook that exists now from `solito/link`, adapted for the App Router. You can call this to create accessible, custom link components.

### `solito/link`

`Link` and `TextLink` components are now marked with `use client`, making them compatible with RSC and the App Router.

[See the docs for Link.](https://solito.dev/usage/link)

### `solito/image`

`SolitoImage` is now marked with `use client`, making it compatible with RSC and the App Router.

[See the docs for Image.](/usage/image)

### `solito/moti`

To use the [`MotiLink`](/usage/moti-link) component in the App Directory, you should import it from `solito/moti/app`.

[See the docs for MotiLink.](https://solito.dev/usage/moti-link)

## Setup

Before you can start using the App Directory, you need to add some minimal setup.

### `/app/layout.tsx`

Clear out the `layout.tsx` file to look like this:

```tsx
import { StylesProvider } from './styles-provider'
import './globals.css'

export const metadata = {
  title: 'Create Solito App',
  description: 'Generated by create Solito app',
}

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>
        <StylesProvider>{children}</StylesProvider>
      </body>
    </html>
  )
}
```

Notice that we have two imports at the top. Let's implement those next.

### `/app/styles-provider.tsx`

`StylesProvider` should look like this (you can copy-paste it):

<details>

<summary>Click to view code</summary>

```tsx
// @ts-nocheck
'use client'
import { useServerInsertedHTML } from 'next/navigation'
import { StyleSheet } from 'react-native'

export function StylesProvider({ children }: { children: React.ReactNode }) {
  useServerInsertedHTML(() => {
    // if you use Tamagui, you should add its sheet here too.
    const sheet = StyleSheet.getSheet()
    return (
      <style
        dangerouslySetInnerHTML={{ __html: sheet.textContent }}
        id={sheet.id}
      />
    )
  })
  return <>{children}</>
}
```

</details>

### `/app/globals.css`

Finally, add this CSS reset:

<details>

<summary>Click to view code</summary>

```css
html,
body,
#__next {
  width: 100%;
  /* To smooth any scrolling behavior */
  -webkit-overflow-scrolling: touch;
  margin: 0px;
  padding: 0px;
  /* Allows content to fill the viewport and go beyond the bottom */
  min-height: 100%;
}
#__next {
  flex-shrink: 0;
  flex-basis: auto;
  flex-direction: column;
  flex-grow: 1;
  display: flex;
  flex: 1;
}
html {
  scroll-behavior: smooth;
  /* Prevent text size change on orientation change https://gist.github.com/tfausak/2222823#file-ios-8-web-app-html-L138 */
  -webkit-text-size-adjust: 100%;
  height: 100%;
}
body {
  display: flex;
  /* Allows you to scroll below the viewport; default value is visible */
  overflow-y: auto;
  overscroll-behavior-y: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  -ms-overflow-style: scrollbar;
}
```

</details>

**That's it!**

### `_document.tsx`/`_app.tsx`

You can start using the App Router with Solito without changing those existing files.

## Example Monorepos

The Solito example monorepos have not yet moved to the App Router.

That said, there is a [Solito + Next.js App Directory example](https://github.com/nandorojo/solito/tree/master/develop/appdir), which should be a useful reference for the setup.

## React Server Components

Please note that the root of your page will often be marked with `use client` for React Native Web compatibility.

In the future, Tamagui may support React Server Components, so you can use that if you want to use RSC down the line. Until RSC is implemented on the native side, you likely won't find yourself using them in a Solito app.

That said, the Next.js App Router has many additional features (like nested layouts) that will be useful without RSC.

## Follow the Next.js Docs

Please reference the [official Next.js docs for using the App Router](https://nextjs.org/docs/app/building-your-application/upgrading/app-router-migration).
